<?php

class MovieController extends Controller {

    /**
     * @var string the default layout for the views. Defaults to '//layouts/column2', meaning
     * using two-column layout. See 'protected/views/layouts/column2.php'.
     */
    public $layout = 'backend.views.layouts.column2';

    /**
     * @return array action filters
     */
    public function filters() {
        return array(
            'accessControl', // perform access control for CRUD operations
            'postOnly + delete', // we only allow deletion via POST request
        );
    }

    /**
     * Specifies the access control rules.
     * This method is used by the 'accessControl' filter.
     * @return array access control rules
     */
    public function accessRules() {
        return array(
            array('allow', // allow all users to perform 'index' and 'view' actions
                'actions' => array('index', 'view'),
                'users' => array('*'),
            ),
            array('allow', // allow authenticated user to perform 'create' and 'update' actions
                'actions' => array('create', 'update'),
                'users' => array('@'),
            ),
            array('allow', // allow admin user to perform 'admin' and 'delete' actions
                'actions' => array('admin', 'delete'),
                'users' => array('admin'),
            ),
            array('deny', // deny all users
                'users' => array('*'),
            ),
        );
    }

    /**
     * Displays a particular model.
     * @param integer $id the ID of the model to be displayed
     */
    public function actionView($id) {
        $this->render('view', array(
            'model' => $this->loadModel($id),
            'actors' => join(', ', MovieActor::model()->findActorsByMovie($id)),
            'companies' => join(', ', MovieCompany::model()->findCompaniesByMovie($id)),
            'countries' => join(', ', MovieCountry::model()->findCountriesByMovie($id)),
            'directors' => join(', ', MovieDirector::model()->findDirectorsByMovie($id)),
            'genres' => join(', ', MovieGenre::model()->findGenresByMovie($id)),
            'producers' => join(', ', MovieProducer::model()->findProducersByMovie($id)),
            'screenwriters' => join(', ', MovieScreenwriter::model()->findScreenwritersByMovie($id)),
        ));
    }

    /**
     * Creates a new model.
     * If creation is successful, the browser will be redirected to the 'view' page.
     */
    public function actionCreate() {
        $model = new MovieForm;
        // uncomment the following code to enable ajax-based validation
        /*
          if(isset($_POST['ajax']) && $_POST['ajax']==='movie-form-create-form')
          {
          echo CActiveForm::validate($model);
          Yii::app()->end();
          }
         */
        if (isset($_POST['MovieForm'])) {
            $model->attributes = $_POST['MovieForm'];
            if ($model->validate()) {
                $wikipadiaParser = new WikipediaParser();
                $info = $wikipadiaParser->parseMovie($model->wikipediaUrl);
                if (isset($info['language']) && isset($info['title'])) {
                    $languageId = Language::model()->findIdByCode($info['language']);
                    $movie = array();
                    // Set info from model
                    $movie['language_id'] = $languageId;
                    $movie['wikipedia_url'] = urldecode($model->wikipediaUrl);
                    $movie['youtube_id'] = $model->youtubeId;
                    $movie['kp_id'] = $model->kpId;
                    $movie['source_image'] = $model->sourceImage;
                    $movie['free_image'] = $model->freeImage;
                    // Set wikipedia info
                    $movie['title'] = $info['title'];
                    $movie['code'] = Transliterator::encodeText($movie['title']);
                    // Process image
                    if (isset($info['image'])) {
                        $imageProcessor = new ImageProcessor();
                        $filename = 'movie/' . str_replace('-', '_', $movie['code']) . '.jpg';
                        if ($imageProcessor->saveImage($info['image'], $filename)) {
                            $movie['image'] = $filename;
                            $smallFilename = preg_replace('/\.jpg$/', '_small.jpg', $filename);
                            if ($imageProcessor->crateSmallImage($filename, $smallFilename)) {
                                $movie['small_image'] = $smallFilename;
                            }
                        }
                    }
                    if (isset($info['subject'])) {
                        $movie['subject'] = $info['subject'];
                    }
                    if (isset($info['duration'])) {
                        $movie['duration'] = intval($info['duration']) * 3600;
                    }
                    if (isset($info['year'])) {
                        $movie['year'] = $info['year'];
                    }
                    // Process rating
                    if ($model->kpId) {
                        $ratingParser = new KinopoiskParser();
                        $rating = $ratingParser->parseRating($model->kpId);
                        if ($rating) {
                            $movie['kp_rating'] = $rating['kp_rating'];
                            $movie['imdb_rating'] = $rating['imdb_rating'];
                        }
                    }
                    // Save movie info
                    $movieModel = Movie::model();
                    $movieModel->isNewRecord = true;
                    $movieModel->attributes = $movie;
                    if ($movieModel->save()) {
                        $movieId = $movieModel->id;
                        // Process actors
                        if (isset($info['actors'])) {
                            $this->_processMovieActors($info['actors'], $movieId, $languageId);
                        }
                        // Process companies
                        if (isset($info['companies'])) {
                            $this->_processMovieCompanies($info['companies'], $movieId, $languageId);
                        }
                        // Process countries
                        if (isset($info['countries'])) {
                            $this->_processMovieCountries($info['countries'], $movieId, $languageId);
                        }
                        // Process directors
                        if (isset($info['directors'])) {
                            $this->_processMovieDirectors($info['directors'], $movieId, $languageId);
                        }
                        // Process genres
                        if (isset($info['genres'])) {
                            $this->_processMovieGenres($info['genres'], $movieId, $languageId);
                        }
                        // Process producers
                        if (isset($info['producers'])) {
                            $this->_processMovieProducers($info['producers'], $movieId, $languageId);
                        }
                        // Process screenwriters
                        if (isset($info['screenwriters'])) {
                            $this->_processMovieScreenwriters($info['screenwriters'], $movieId, $languageId);
                        }
                        $this->redirect(array('view', 'id' => $movieId));
                    } else {
                        echo $movieModel->getErrors();
                    }
                }
            }
        }
        $this->render('create', array('model' => $model));
    }

    /**
     * Updates a particular model.
     * If update is successful, the browser will be redirected to the 'view' page.
     * @param integer $id the ID of the model to be updated
     */
    public function actionUpdate($id) {
        $model = $this->loadModel($id);

        // Uncomment the following line if AJAX validation is needed
        // $this->performAjaxValidation($model);

        if (isset($_POST['Movie'])) {
            $model->attributes = $_POST['Movie'];
            $model->code = Transliterator::encodeText($model->title);
            // Process rating
            if ($model->kp_id) {
                $ratingParser = new KinopoiskParser();
                $rating = $ratingParser->parseRating($model->kp_id);
                if ($rating) {
                    $model->kp_rating = $rating['kp_rating'];
                    $model->imdb_rating = $rating['imdb_rating'];
                }
            }
            if ($model->save())
                $this->redirect(array('view', 'id' => $model->id));
        }

        $languages = Language::model()->findPairs();
        $this->render('update', array(
            'model' => $model,
            'languages' => $languages
        ));
    }

    /**
     * Deletes a particular model.
     * If deletion is successful, the browser will be redirected to the 'admin' page.
     * @param integer $id the ID of the model to be deleted
     */
    public function actionDelete($id) {
        $model = $this->loadModel($id);
        // Delete images
        $imageProcessor = new ImageProcessor();
        if ($model->image) {
            $imageProcessor->removeImage($model->image);
        }
        if ($model->small_image) {
            $imageProcessor->removeImage($model->small_image);
        }
        $model->delete();
        // Delete children
        MovieActor::model()->deleteByMovie($id);
        MovieCompany::model()->deleteByMovie($id);
        MovieCountry::model()->deleteByMovie($id);
        MovieDirector::model()->deleteByMovie($id);
        MovieGenre::model()->deleteByMovie($id);
        MovieProducer::model()->deleteByMovie($id);
        MovieScreenwriter::model()->deleteByMovie($id);

        // if AJAX request (triggered by deletion via admin grid view), we should not redirect the browser
        if (!isset($_GET['ajax']))
            $this->redirect(isset($_POST['returnUrl']) ? $_POST['returnUrl'] : array('admin'));
    }

    /**
     * Lists all models.
     */
    public function actionIndex() {
        $dataProvider = new CActiveDataProvider('Movie');
        $this->render('index', array(
            'dataProvider' => $dataProvider,
        ));
    }

    /**
     * Manages all models.
     */
    public function actionAdmin() {
        $model = new Movie('search');
        $model->unsetAttributes();  // clear any default values
        if (isset($_GET['Movie']))
            $model->attributes = $_GET['Movie'];

        $languages = Language::model()->findPairs();
        $this->render('admin', array(
            'model' => $model,
            'languages' => $languages
        ));
    }

    /**
     * Returns the data model based on the primary key given in the GET variable.
     * If the data model is not found, an HTTP exception will be raised.
     * @param integer $id the ID of the model to be loaded
     * @return Movie the loaded model
     * @throws CHttpException
     */
    public function loadModel($id) {
        $model = Movie::model()->findByPk($id);
        if ($model === null)
            throw new CHttpException(404, 'The requested page does not exist.');
        return $model;
    }

    /**
     * Performs the AJAX validation.
     * @param Movie $model the model to be validated
     */
    protected function performAjaxValidation($model) {
        if (isset($_POST['ajax']) && $_POST['ajax'] === 'movie-form') {
            echo CActiveForm::validate($model);
            Yii::app()->end();
        }
    }

    /**
     * Process movie actors
     * 
     * @param array $actors     Contains array of actor names
     * @param int $movieId      Contains ID of movie
     * @param int $languageId   Contains ID of language
     * 
     */
    private function _processMovieActors($actors, $movieId, $languageId) {
        $actorModel = Actor::model();
        $movieActorModel = MovieActor::model();
        foreach ($actors as $actor) {
            $actor = trim($actor);
            $actorId = $actorModel->findIdByNameAndLanguage($actor, $languageId);
            if (!$actorId) {
                $actorModel->isNewRecord = true;
                $actorModel->id = null;
                $actorModel->attributes = array('name' => $actor, 'language_id' => $languageId);
                if ($actorModel->save()) {
                    $actorId = $actorModel->id;
                }
            }
            if ($actorId) {
                $movieActorModel->isNewRecord = true;
                $movieActorModel->attributes = array('movie_id' => $movieId, 'actor_id' => $actorId);
                $movieActorModel->save();
            }
        }
    }

    /**
     * Process movie companies
     * 
     * @param array $companies     Contains array of company names
     * @param int $movieId      Contains ID of movie
     * @param int $languageId   Contains ID of language
     * 
     */
    private function _processMovieCompanies($companies, $movieId, $languageId) {
        $companyModel = Company::model();
        $movieCompanyModel = MovieCompany::model();
        foreach ($companies as $company) {
            $company = trim($company);
            $companyId = $companyModel->findIdByNameAndLanguage($company, $languageId);
            if (!$companyId) {
                $companyModel->isNewRecord = true;
                $companyModel->id = null;
                $companyModel->attributes = array('name' => $company, 'language_id' => $languageId);
                if ($companyModel->save()) {
                    $companyId = $companyModel->id;
                }
            }
            if ($companyId) {
                $movieCompanyModel->isNewRecord = true;
                $movieCompanyModel->attributes = array('movie_id' => $movieId, 'company_id' => $companyId);
                $movieCompanyModel->save();
            }
        }
    }

    /**
     * Process movie countries
     * 
     * @param array $countries  Contains array of country names
     * @param int $movieId      Contains ID of movie
     * @param int $languageId   Contains ID of language
     * 
     */
    private function _processMovieCountries($countries, $movieId, $languageId) {
        $countryModel = Country::model();
        $movieCountryModel = MovieCountry::model();
        foreach ($countries as $country) {
            $country = trim($country);
            $countryId = $countryModel->findIdByNameAndLanguage($country, $languageId);
            if (!$countryId) {
                $countryModel->isNewRecord = true;
                $countryModel->id = null;
                $countryModel->attributes = array('name' => $country, 'language_id' => $languageId);
                if ($countryModel->save()) {
                    $countryId = $countryModel->id;
                }
            }
            if ($countryId) {
                $movieCountryModel->isNewRecord = true;
                $movieCountryModel->attributes = array('movie_id' => $movieId, 'country_id' => $countryId);
                $movieCountryModel->save();
            }
        }
    }

    /**
     * Process movie directors
     * 
     * @param array $directors  Contains array of director names
     * @param int $movieId      Contains ID of movie
     * @param int $languageId   Contains ID of language
     * 
     */
    private function _processMovieDirectors($directors, $movieId, $languageId) {
        $directorModel = Director::model();
        $movieDirectorModel = MovieDirector::model();
        foreach ($directors as $director) {
            $director = trim($director);
            $directorId = $directorModel->findIdByNameAndLanguage($director, $languageId);
            if (!$directorId) {
                $directorModel->isNewRecord = true;
                $directorModel->id = null;
                $directorModel->attributes = array('name' => $director, 'language_id' => $languageId);
                if ($directorModel->save()) {
                    $directorId = $directorModel->id;
                }
            }
            if ($directorId) {
                $movieDirectorModel->isNewRecord = true;
                $movieDirectorModel->attributes = array('movie_id' => $movieId, 'director_id' => $directorId);
                $movieDirectorModel->save();
            }
        }
    }

    /**
     * Process movie genres
     * 
     * @param array $genres  Contains array of genre names
     * @param int $movieId      Contains ID of movie
     * @param int $languageId   Contains ID of language
     * 
     */
    private function _processMovieGenres($genres, $movieId, $languageId) {
        $genreModel = Genre::model();
        $movieGenreModel = MovieGenre::model();
        foreach ($genres as $genre) {
            $genre = trim($genre);
            $genreId = $genreModel->findIdByNameAndLanguage($genre, $languageId);
            if (!$genreId) {
                $genreModel->isNewRecord = true;
                $genreModel->id = null;
                $genreModel->attributes = array('name' => $genre, 'language_id' => $languageId);
                if ($genreModel->save()) {
                    $genreId = $genreModel->id;
                }
            }
            if ($genreId) {
                $movieGenreModel->isNewRecord = true;
                $movieGenreModel->attributes = array('movie_id' => $movieId, 'genre_id' => $genreId);
                $movieGenreModel->save();
            }
        }
    }

    /**
     * Process movie producers
     * 
     * @param array $producers  Contains array of producer names
     * @param int $movieId      Contains ID of movie
     * @param int $languageId   Contains ID of language
     * 
     */
    private function _processMovieProducers($producers, $movieId, $languageId) {
        $producerModel = Producer::model();
        $movieProducerModel = MovieProducer::model();
        foreach ($producers as $producer) {
            $producer = trim($producer);
            $producerId = $producerModel->findIdByNameAndLanguage($producer, $languageId);
            if (!$producerId) {
                $producerModel->isNewRecord = true;
                $producerModel->id = null;
                $producerModel->attributes = array('name' => $producer, 'language_id' => $languageId);
                if ($producerModel->save()) {
                    $producerId = $producerModel->id;
                }
            }
            if ($producerId) {
                $movieProducerModel->isNewRecord = true;
                $movieProducerModel->attributes = array('movie_id' => $movieId, 'producer_id' => $producerId);
                $movieProducerModel->save();
            }
        }
    }

    /**
     * Process movie screenwriters
     * 
     * @param array $screenwriters  Contains array of screenwriter names
     * @param int $movieId      Contains ID of movie
     * @param int $languageId   Contains ID of language
     * 
     */
    private function _processMovieScreenwriters($screenwriters, $movieId, $languageId) {
        $screenwriterModel = Screenwriter::model();
        $movieScreenwriterModel = MovieScreenwriter::model();
        foreach ($screenwriters as $screenwriter) {
            $screenwriter = trim($screenwriter);
            $screenwriterId = $screenwriterModel->findIdByNameAndLanguage($screenwriter, $languageId);
            if (!$screenwriterId) {
                $screenwriterModel->isNewRecord = true;
                $screenwriterModel->id = null;
                $screenwriterModel->attributes = array('name' => $screenwriter, 'language_id' => $languageId);
                if ($screenwriterModel->save()) {
                    $screenwriterId = $screenwriterModel->id;
                }
            }
            if ($screenwriterId) {
                $movieScreenwriterModel->isNewRecord = true;
                $movieScreenwriterModel->attributes = array('movie_id' => $movieId, 'screenwriter_id' => $screenwriterId);
                $movieScreenwriterModel->save();
            }
        }
    }

}
